package org.xs.web.http.velocity;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletContext;

import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.runtime.RuntimeConstants;
import org.xs.web.util.Resources;

 

public class VelocityConfigurer {
	//default velocity.properties location
	private String configLocation = "WEB-INF/conf/velocity.properties";
	private String resourceLoaderPath = "/"; 
	private ServletContext servletContext;
	
	public VelocityConfigurer(){
		
	}
	public VelocityConfigurer(ServletContext context){
		this.servletContext = context;
	}
	
	public VelocityEngine createVelocityEngine() throws IOException, VelocityException {
		VelocityEngine velocityEngine = new VelocityEngine();
		Properties velocityProperties = loadVelocityProperties();
		File resourceUrl = new File(servletContext.getRealPath(""));
		if(resourceUrl != null){
			initVelocityResourceLoader(velocityEngine, resourceUrl);
		}
		for (Iterator it = velocityProperties.entrySet().iterator(); it.hasNext();) {
			Map.Entry entry = (Map.Entry) it.next();
			if (!(entry.getKey() instanceof String)) {
				throw new IllegalArgumentException(
						"Illegal property key [" + entry.getKey() + "]: only Strings allowed");
			}
			velocityEngine.setProperty((String) entry.getKey(), entry.getValue());
		}
		try {
			velocityEngine.init();
		}
		catch (IOException ex) {
			throw ex;
		}
		catch (VelocityException ex) {
			throw ex;
		}
		catch (RuntimeException ex) {
			throw ex;
		}
		catch (Exception ex) {
			throw new VelocityException(ex.toString());
		}	
		return velocityEngine;
	}
	
	protected void initVelocityResourceLoader(VelocityEngine velocityEngine, File resourceLoaderUrl) {
				velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "file");
				velocityEngine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_CACHE, "true");
				velocityEngine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, resourceLoaderUrl.getPath());
	}

	public Properties loadVelocityProperties() throws IOException {
		Properties velocityProperties = new Properties();
		InputStream in = Resources.getResourceAsStream(configLocation,servletContext);
		velocityProperties.load(in);
		Resources.closeStream(in);
		return velocityProperties;
	}
	
	protected VelocityEngine newVelocityEngine() throws IOException, VelocityException {
		return new VelocityEngine();
	}
	public static void main(String[] args) throws VelocityException, IOException {
		VelocityConfigurer v = new VelocityConfigurer();
		v.createVelocityEngine();
	}
}
